<template>
  <div class="map-editor">
    <!-- 地图容器 -->
    <div ref="mapContainer" class="map-container">
      <!-- 地图容器 -->
      <div id="map-box" class="map-box">
        <!-- 地图将在这里加载 -->
      </div>
    </div>
    
    <!-- 工具栏 -->
    <ToolBar @selectTool="handleDrawTool"/>

    <!-- 右侧面板：随机点与智能排序 -->
    <RightPanel 
      :points-count="generatedPoints.length" 
      :points="generatedPoints"
      :original="originalOrder"
      :optimized="optimizedOrder"
      v-model:loading="sorting"
      @generatePoints="handleGeneratePoints" 
      @smartSort="handleSmartSort" 
    />
    
    <!-- 图层面板 -->
    <!-- <LayerPanel /> -->
    
    <!-- 状态栏 -->
    <div class="status-bar">
      <span>绘制模式: {{ drawModeText }}</span>
      <span v-if="drawState.isDrawing">| 绘制中...</span>
      <span v-if="analysisResult">| 分析结果: {{ analysisResult.message }}</span>
      <!-- <span>| 图层数量: {{ layers.length }}</span> -->
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useMapStore } from '../../stores/map'
import { 
  MapUtils, 
  DrawUtils, 
  checkPointsInPolygon, 
  checkLineClosure, 
  generateAnalysisMessage, 
  getDetailedReport,
  testPoints,
  drawConfig,
  euclideanDistance,
  heldKarpPath,
  gaTwoOpt
} from '../../utils'
import { ElMessage } from 'element-plus'
import ToolBar from './ToolBar.vue'
import RightPanel from './RightPanel.vue'

const mapContainer = ref(null)
const mapStore = useMapStore()
const { drawMode, drawState, layers, mapConfig, startPoint, generatedPoints, originalOrder, optimizedOrder } = storeToRefs(mapStore)

// 分析结果状态
const analysisResult = ref(null)

let mapInstance = null
let drawUtils = null
let tspWorker = null
const sorting = ref(false)

// 初始化演示点（可被右侧面板覆盖）
const clickPoints = testPoints

// 初始化地图
const initMap = async () => {
  try {
    // 初始化腾讯地图
    mapInstance = await MapUtils.initMap('map-box', {
      center: mapConfig.value.center,
      zoom: mapConfig.value.zoom,
      minZoom: mapConfig.value.minZoom,
      maxZoom: mapConfig.value.maxZoom
    })
    
    // 保存地图实例到状态管理
    mapStore.setMapInstance(mapInstance)
    
    // 初始化绘制工具
    drawUtils = new DrawUtils(mapInstance,handleDrawComplete)
    
    // 绑定地图事件
    MapUtils.bindMapEvents(mapInstance, {
      // click: handleMapClick,
      dblclick: handleMapDoubleClick,
      zoom: handleMapZoom
    })
    // 展示点位
    // 初始展示 demo 点（后续会被生成点集合覆盖重绘）
    // const multiMarker = new TMap.MultiMarker({
    //   map: mapInstance,
    //   points: clickPoints,
    //   styles: { //点标注的相关样式
    //         "marker": new TMap.MarkerStyle({
    //             "width": 25,
    //             "height": 35,
    //             "anchor": { x: 16, y: 32 },
    //         })
    //     },
    //     geometries: clickPoints.map(item => ({
    //       id: item.id,
    //       styleId: 'marker',
    //       position: new TMap.LatLng(item.lat, item.lng),
    //       properties: {
    //         title: '点位' + item.id
    //       }
    //     }))
    // })

    ElMessage.success('地图初始化成功')
  } catch (error) {
    console.error('地图初始化失败:', error)
    ElMessage.error('地图初始化失败')
  }
}

// 地图点击事件
const handleMapClick = (event) => {
  console.log('地图点击:', event)
  
  // 根据当前绘制模式执行不同逻辑
  switch (drawMode.value) {
    case 'none':
      // 选择模式：点击选择已有图形
      console.log('选择模式：点击选择图形')
      break
      
    case 'point':
      // 点绘制模式：直接创建标记点
      console.log('点绘制模式：创建标记点', event.lngLat)
      if (drawUtils) {
        drawUtils.drawPoint(event.lngLat)
      }
  
      
    case 'line':
      // 线绘制模式：添加线段顶点
      console.log('线绘制模式：添加顶点', event.lngLat)
      if (drawUtils) {
        drawUtils.addLinePoint(event.lngLat)
      }
      break

    case 'free_line':
      // 自由线绘制模式：添加线段顶点
      console.log('自由线绘制模式：添加顶点', event.lngLat)
      mapInstance.setDraggable(false)
      if (drawUtils) {
        drawUtils.startDrawFreeLine({
          isDraggable: false,
          eventType: 'mousedown'
        })
      }
      break
      
    case 'polygon':
      // 多边形模式：添加多边形顶点
      console.log('多边形模式：添加顶点', event.lngLat)
      if (drawUtils) {
        drawUtils.addPolygonPoint(event.lngLat)
      }
      break
      
    case 'circle':
      // 圆形模式：确定圆心
      console.log('圆形模式：确定圆心', event.lngLat)
      if (drawUtils) {
        drawUtils.startCircle(event.lngLat)
      }
      break
      
    case 'rectangle':
      // 矩形模式：确定起点
      console.log('矩形模式：确定起点', event.lngLat)
      if (drawUtils) {
        drawUtils.startRectangle(event.lngLat)
      }
      break
  }
}

// 地图双击事件
const handleMapDoubleClick = (event) => {
  console.log('地图双击:', event)
  // 根据当前绘制模式完成绘制
  if (drawUtils) {
    switch (drawMode.value) {
      case 'point':
        drawUtils.finishPoint()
        break
      case 'line':
        drawUtils.finishLine()
        break
      case 'polygon':
        drawUtils.finishPolygon()
        break
      case 'circle':
        drawUtils.finishCircle()
        break
      case 'rectangle':
        drawUtils.finishRectangle()
        break
    }
  }
}

// 地图鼠标按下事件
const handleMapMouseDown = (event) => {
  console.log('地图鼠标按下:', event)
  
  // 根据当前绘制模式调用对应的绘制方法
  if (drawMode.value !== 'none') {
    if (drawMode.value === 'free_line') {
      mapInstance.setDraggable(false)
    }
    drawUtils.startDraw(drawMode.value, event.lngLat)
  }
}

// 地图鼠标抬起事件
const handleMapMouseUp = (event) => {
  console.log('地图鼠标抬起:', event)
  
  // 根据当前绘制模式完成绘制
  if (drawMode.value === 'free_line') {
    mapInstance.setDraggable(true)
    mapStore.layers.length = 0
    mapStore.clearDrawState()
    drawUtils.finishDrawFreeLine()
  } else if (drawMode.value === 'circle') {
    drawUtils.finishDrawCircle()
  } else if (drawMode.value === 'rectangle') {
    drawUtils.finishDrawRectangle()
  }
}

// 地图鼠标移动事件
const handleMapMouseMove = (event) => {
  // 根据当前绘制模式处理移动事件
  if (drawMode.value === 'free_line') {
    drawUtils.continueDrawFreeLine(event.lngLat)
  } else if (drawMode.value === 'circle') {
    drawUtils.updateDrawCircle(event.lngLat)
  } else if (drawMode.value === 'rectangle') {
    drawUtils.updateDrawRectangle(event.lngLat)
  }
}

// 地图缩放事件
const handleMapZoom = (event) => {
  // console.log('地图缩放:', event)
}

// 绘制模式文本
const drawModeText = computed(() => {
  const texts = {
    none: '选择',
    point: '标记点',
    free_line: '自由线',
    line: '直线',
    polygon: '多边形',
    circle: '圆形',
    rectangle: '矩形'
  }
  return texts[drawMode.value] || '未知'
})

// 绘制工具选择事件
const handleDrawTool = (tool) => {
  // console.log('绘制工具选择:', tool)
  // mapStore.setDrawMode(tool)
  // 挂载相应的事件
  handleMapClick(tool)
}

// 绘制完成回调
const handleDrawComplete = async (data) => {
  console.log('绘制完成:', data)
  
  // 如果绘制的是自由线且形成了闭合区域，则判断点是否在区域内
  if (data.type === 'free_line' && data.data && data.data.length > 2) {
    // 使用工具函数检查是否形成闭合区域
    const closureResult = checkLineClosure(data.data, drawConfig.closureThreshold)
    
    if (closureResult.isClosed) {
      // 使用工具函数进行点位置分析
      const analysisResult = await checkPointsInPolygon(data.data, clickPoints)
      showPointsAnalysisResult(analysisResult)
    } else {
      console.log('绘制的线未形成闭合区域，无法判断点是否在区域内')
      ElMessage.warning(closureResult.reason)
    }
  }
}



// 在界面上显示分析结果
const showPointsAnalysisResult = (analysisResult) => {
  // 使用工具函数生成消息
  const message = generateAnalysisMessage(analysisResult)
  console.log(message)
  
  // 设置分析结果到状态
  analysisResult.value = {
    message,
    pointsInPolygon: analysisResult.pointsInPolygon,
    pointsOutsidePolygon: analysisResult.pointsOutsidePolygon,
    totalPoints: analysisResult.totalPoints
  }
  
  // 根据分析结果显示不同类型的消息
  if (analysisResult.success) {
    ElMessage.success(message)
  } else {
    ElMessage.error(message)
  }
}

// 生成北京范围内的随机点
const generateRandomPointsInBeijing = (count) => {
  // 北京市大致经纬度范围（简化边界）：
  // lat: [39.6, 40.2]  lng: [116.0, 116.8]
  const minLat = 39.6, maxLat = 40.2
  const minLng = 116.0, maxLng = 116.8
  const pts = []
  for (let i = 0; i < count; i++) {
    const lat = +(minLat + Math.random() * (maxLat - minLat)).toFixed(6)
    const lng = +(minLng + Math.random() * (maxLng - minLng)).toFixed(6)
    pts.push({ id: i + 1, lat, lng, name: `点${i + 1}` })
  }
  return pts
}

// 生成带数字的图标（Canvas 动态绘制，数字内嵌到图标中，避免缩放级别影响可见性）
const createNumberedIcon = (num) => {
  const size = 36
  const canvas = document.createElement('canvas')
  canvas.width = size
  canvas.height = size
  const ctx = canvas.getContext('2d')
  ctx.fillStyle = '#409eff'
  ctx.beginPath()
  ctx.arc(size / 2, size / 2, size / 2 - 2, 0, Math.PI * 2)
  ctx.fill()
  ctx.fillStyle = '#fff'
  ctx.font = 'bold 16px Arial'
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.fillText(String(num), size / 2, size / 2)
  return canvas.toDataURL('image/png')
}

// 根据点集合在地图上渲染标注（按顺序标号）
let generatedMarkerLayer = null
let generatedLabelLayer = null
let generatedPathLayer = null
const renderGeneratedPoints = (points) => {
  if (!mapInstance) return
  if (generatedMarkerLayer) {
    generatedMarkerLayer.setMap(null)
    generatedMarkerLayer = null
  }
  if (generatedLabelLayer) {
    generatedLabelLayer.setMap(null)
    generatedLabelLayer = null
  }
  if (generatedPathLayer) {
    generatedPathLayer.setMap(null)
    generatedPathLayer = null
  }
  if (!points || points.length === 0) return
  // 使用带数字的自定义图标样式，替代文字标签，确保任意缩放级别数字可见
  const styles = {}
  const geometries = points.map((p, idx) => {
    const styleId = `num-${idx + 1}`
    styles[styleId] = new TMap.MarkerStyle({
      width: 32,
      height: 32,
      anchor: { x: 16, y: 16 },
      src: createNumberedIcon(idx + 1)
    })
    return {
      id: String(p.id ?? idx + 1),
      styleId,
      position: new TMap.LatLng(p.lat, p.lng),
      properties: { title: `${idx + 1}. (${p.lat}, ${p.lng})` }
    }
  })
  generatedMarkerLayer = new TMap.MultiMarker({
    map: mapInstance,
    styles,
    geometries
  })
  // 鼠标悬停显示信息
  generatedMarkerLayer.on('mouseover', (evt) => {
    if (!evt || !evt.geometry) return
    const idx = geometries.findIndex(g => g.id === evt.geometry.id)
    if (idx >= 0) {
      const p = points[idx]
      ElMessage.info(`${idx + 1}号点: lat=${p.lat}, lng=${p.lng}`)
    }
  })

}

// 响应右侧面板：生成点
const handleGeneratePoints = (count) => {
  const pts = generateRandomPointsInBeijing(count)
  // 为每个点赋予稳定名称（不随排序变化）
  const named = pts.map((p, i) => ({ ...p, id: i + 1, name: p.name || `点-${i + 1}` }))
  mapStore.setGeneratedPoints(named)
  // 原始顺序为生成时的 id 顺序
  mapStore.setOriginalOrder(named.map(p => p.id))
  mapStore.setOptimizedOrder([])
  renderGeneratedPoints(pts)
  ElMessage.success(`已生成 ${count} 个随机点并展示在地图上`)
}

// 智能排序：根据数量选择算法，从天安门出发
const handleSmartSort = () => {
  const pts = generatedPoints.value
  if (!pts || pts.length === 0) { ElMessage.warning('请先生成坐标点'); return }
  if (sorting.value) return
  sorting.value = true
  // 懒加载 worker
  if (!tspWorker) {
    tspWorker = new Worker(new URL('../../workers/tspWorker.js', import.meta.url), { type: 'module' })
    tspWorker.onmessage = (e) => {
      console.log('排序完成:', e.data)
      sorting.value = false
      const { order, error } = e.data || {}
      if (error) { ElMessage.error('排序失败：' + error); return }
      if (!Array.isArray(order)) { ElMessage.error('排序失败：无结果'); return }
      const current = generatedPoints.value
      const optimizedIds = order.map(idx => current[idx].id)
      mapStore.setOptimizedOrder(optimizedIds)
      const reordered = order.map(idx => current[idx])
      mapStore.setGeneratedPoints(reordered)
      renderGeneratedPoints(reordered)
      ElMessage.success('已完成智能排序并重新渲染标注')
    }
    tspWorker.onerror = (e) => { sorting.value = false; ElMessage.error('排序线程错误') }
  }
  // 将响应式数据转换为可克隆的纯对象，避免 DataCloneError
  const ptsPlain = pts.map(p => ({ id: p.id, name: p.name, lat: p.lat, lng: p.lng }))
  const sp = startPoint.value
  const startPlain = { lat: sp.lat, lng: sp.lng }
  tspWorker.postMessage({ points: ptsPlain, start: startPlain })
}

// 当集合变化时自动重绘
watch(generatedPoints, (pts) => {
  renderGeneratedPoints(pts)
}, { deep: true })

onMounted(() => {
  // 组件挂载后自动初始化地图
  console.log('地图编辑器组件已挂载')
  // 延迟初始化，确保DOM已经渲染
  setTimeout(() => {
    initMap()
  }, 100)
})
</script>

<style scoped>
.map-editor {
  position: relative;
  width: 100%;
  height: 100vh;
  background-color: #f0f2f5;
  overflow: hidden;
}

.map-container {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}

.map-box {
  width: 100%;
  height: 100%;
  background-color: #f5f7fa;
  position: relative;
}

.status-bar {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 32px;
  background-color: rgba(0, 0, 0, 0.8);
  color: white;
  display: flex;
  align-items: center;
  padding: 0 16px;
  font-size: 12px;
  gap: 16px;
  z-index: 1000;
}
</style> 